<?php

declare(strict_types=1);

namespace app\eslib;

/**
 * 验证扩展类
 * 提供输入校验能力
 * @version 1.0.0
 * 支持 ThinkPHP 6.x 验证规则
 * 支持 Laravel 9.x 验证规则
 * @see https://www.kancloud.cn/manual/thinkphp6_0/1037629
 * @see https://learnku.com/docs/laravel/9.x/validation/12219
 * @link docs/EsValidate.md
 */
class EsValidate
{
    /**
     * 自动检测框架提供商
     */
    static private function getProvider()
    {
        $classes = [
            'thinkphp6' => '\think\Request',
            'laravel9' => '\Illuminate\Http\Response'
        ];
        foreach ($classes as $provider => $class) {
            if (class_exists($class)) {
                return $provider;
            }
        }
        return '';
    }

    /**
     * 使用 ThinkPHP6 进行数据校验
     */
    static private function checkByThinkPHP6($rules, $data, $defaults = [])
    {
        // ThinkPHP 原生校验
        $validator =  \think\facade\Validate::rule($rules);
        if (!$validator->check($data)) {
            return EsUtils::stdMessage(false, $validator->getError());
        }

        // 使用默认值补全表单字段，如果字段存在则忽略。
        foreach ($defaults as $k => $v) {
            if (!isset($data[$k])) {
                $data[$k] = $v;
            }
        }
        return EsUtils::stdMessage(true, '', $data);
    }

    /**
     * 使用 Laravel6 进行数据校验
     */
    static private function checkByLaravel9(array $data, array $rules, $defaults = [])
    {
        // 支持 ThinkPHP 的快捷名称写法: 'icon|商品图片' => 'require|max:150'
        $rules2 = [];
        $customAttributes = [];
        foreach ($rules as $k => $v) {
            if (strpos($k, '|')) {
                $names = explode('|', $k, 2);
                $rules2[$names[0]] = $v;
                $customAttributes[$names[0]] = $names[1];
                continue;
            }
            $rules2[$k] = $v;
        }
        $rules = $rules2;
        unset($rules2);

        // Laravel 原生校验
        $messages = [];
        $validator = \Illuminate\Support\Facades\Validator::make($data, $rules, $messages, $customAttributes);
        if ($validator->fails()) {
            return EsUtils::stdmessage(false, $validator->errors());
        }

        // 使用默认值补全表单字段，如果字段存在则忽略。
        foreach ($defaults as $k => $v) {
            if (!isset($data[$k])) {
                $data[$k] = $v;
            }
        }
        return EsUtils::stdMessage(true, '', $data);
    }

    /**
     * 公共数据校验方法
     */
    static public function check($rules, $data, $defaults = [])
    {
        switch (self::getProvider()) {
            case 'thinkphp':
                return self::checkByThinkPHP6($rules, $data, $defaults);
            case 'laravel':
                return self::checkByLaravel9($rules, $data, $defaults);
            default:
                return EsUtils::stdMessage(false, '只支持 Laravel 和 ThinkPHP 框架');
        }
    }

    static public function isSafeInput($str)
    {
        # code...
    }
    static function isOpenid($str)
    {
    }

    static public function isIdCard($str)
    {
        # code...
    }
    static function isTitle($str)
    {
    }
    static public function isSmallint($str)
    {
        # code...
    }
    static public function isTinyint($str)
    {
        # code...
    }
    static  public function isAddress($str)
    {
        # code...
    }
}
